package com.eranga.project;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.speech.tts.TextToSpeech;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;

import com.eranga.project.control.data.AreaCoordinatesDS;
import com.eranga.project.control.data.AreaDS;
import com.eranga.project.model.Area;
import com.eranga.project.model.AreaCoordinates;

public class MainActivity extends Activity implements GPSCallback {
	private GPSManager gpsManager = null;
	private double speed = 0.0;
	Boolean isGPSEnabled = false;
	LocationManager locationManager;
	double currentSpeed, kmphSpeed;
	TextView txtview;
	GPSTracker gpsTracker;
	PolygonLogic logic;
	Speedometer speedometer;
	TextToSpeech tts;
	private int areaId=2;


	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		setContentView(R.layout.main);
		
		speedometer = (Speedometer) findViewById(R.id.Speedometer);
        PowerManager pm = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE);
        WakeLock wakeLock = pm.newWakeLock((PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP), "TAG");
        wakeLock.acquire();
		
		txtview = (TextView) findViewById(R.id.info_message);
		
		txtview.setText(getString(R.string.info));
		

		locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
		gpsManager = new GPSManager(MainActivity.this);
		isGPSEnabled = locationManager
				.isProviderEnabled(LocationManager.GPS_PROVIDER);
		
		logic=new PolygonLogic(MainActivity.this);
		
		if (isGPSEnabled) {
			gpsManager.startListening(getApplicationContext());
			gpsManager.setGPSCallback(this);
		} else {
			gpsManager.showSettingsAlert();
		}
		
		String SETTINGS = "SETTINGS";
		SharedPreferences localSP = getSharedPreferences(SETTINGS, Context.MODE_WORLD_READABLE+ Context.MODE_WORLD_WRITEABLE);

		if(localSP.getString("Status", "").equals("Success")){
			ttsMethod("Welcome to Speed Limit Advisor Android Application.");
			SharedPreferencesClass.setLocalSharedPreference(getApplicationContext(), "Status", "Startup success");
			
		}
		
		
}

	private boolean setPolygon(double lat,double lng) {
	
		AreaCoordinatesDS ds =new AreaCoordinatesDS(getApplicationContext());
		AreaDS  areaDS=new AreaDS(getApplicationContext());
		ArrayList<Area> areas =areaDS.getAllArea();
		
		Log.v("size:", areas.size()+"");
		
		for (Area area : areas) {
			
			ArrayList<AreaCoordinates> list =ds.getAllCoordinates(area.getAreaId());
				
			 if(!list.isEmpty()){
				 
				 if(list.size()==4){
					Log.v("Start","-----------------01---------------------------");
					Log.v("Area Id:", list.get(0).getCoordinateAreaId()+"");
					Log.v("Latitude:", list.get(0).getCoordinateLatitude()+"");
					Log.v("Longitude:", list.get(0).getCoordinateLongitude()+"");
					Log.v("End","--------------------------------------------");
					Log.v("Start","------------------02--------------------------");
					Log.v("Area Id:", list.get(1).getCoordinateAreaId()+"");
					Log.v("Latitude:", list.get(1).getCoordinateLatitude()+"");
					Log.v("Longitude:", list.get(1).getCoordinateLongitude()+"");
					Log.v("End","--------------------------------------------");
					Log.v("Start","------------------03--------------------------");
					Log.v("Area Id:", list.get(2).getCoordinateAreaId()+"");
					Log.v("Latitude:", list.get(2).getCoordinateLatitude()+"");
					Log.v("Longitude:", list.get(2).getCoordinateLongitude()+"");
					Log.v("End","--------------------------------------------");
					Log.v("Start","-----------------04---------------------------");
					Log.v("Area Id:", list.get(3).getCoordinateAreaId()+"");
					Log.v("Latitude:", list.get(3).getCoordinateLatitude()+"");
					Log.v("Longitude:", list.get(3).getCoordinateLongitude()+"");
					Log.v("End","--------------------------------------------");
					
					
					Polygon polygon = Polygon.Builder()
							.addVertex(new Point(list.get(0).getCoordinateLatitude(),list.get(0).getCoordinateLongitude()))
							.addVertex(new Point(list.get(1).getCoordinateLatitude(),list.get(1).getCoordinateLongitude()))
							.addVertex(new Point(list.get(2).getCoordinateLatitude(),list.get(2).getCoordinateLongitude()))
							.addVertex(new Point(list.get(3).getCoordinateLatitude(),list.get(3).getCoordinateLongitude())).build();
					
					
					Boolean status=PolygonLogic.isInside(polygon, new Point(lat, lng));
					Log.v("satuts", status+"");
					
					if(status){
					
						areaId=area.getAreaId();
						return true;
					}
					//polygonValue.setAreaCode(area.getAreaId());
					//polygonValue.setPolygon(polygon);
			 }
			}
		}
		
		//values.add(polygonValue);
		
		return false;
	}

	/*
	 * @ Author Ifras
	 * sample data inserted
	 */
	public void insertSampleData(){
		
		Area area= new Area();
		area.setAreaName("Colombo-04");
		area.setSpeedLimit(40.00);
		int areaId= new AreaDS(this).createArea(area);
		area.setAreaId(areaId);
		
		Area area1= new Area();
		area1.setAreaName("Colombo-06");
		area1.setSpeedLimit(50.00);
		int areaId1= new AreaDS(this).createArea(area1);
		area1.setAreaId(areaId1);
		
		Area area2= new Area();
		area2.setAreaName("Nugegoda");
		area2.setSpeedLimit(60.00);
		int areaId2= new AreaDS(this).createArea(area2);
		area2.setAreaId(areaId2);	
		
		//one polygon 
		AreaCoordinates coordinates =new AreaCoordinates();
		coordinates.setCoordinateLatitude(6.930572);
		coordinates.setCoordinateLongitude(79.864654);
		coordinates.setCoordinateAreaId(areaId);
		int coordinatesId=new AreaCoordinatesDS(this).createAreaCoordinates(coordinates);
		coordinates.setCoordinateId(coordinatesId);
		
		AreaCoordinates coordinates1 =new AreaCoordinates();
		coordinates1.setCoordinateLatitude(6.911486);
		coordinates1.setCoordinateLongitude(79.913406);
		coordinates1.setCoordinateAreaId(areaId);
		int coordinatesId1=new AreaCoordinatesDS(this).createAreaCoordinates(coordinates1);
		coordinates1.setCoordinateId(coordinatesId1);
		
		AreaCoordinates coordinates2 =new AreaCoordinates();
		coordinates2.setCoordinateLatitude(6.885412);
		coordinates2.setCoordinateLongitude(79.856071);
		coordinates2.setCoordinateAreaId(areaId);
		int coordinatesId2=new AreaCoordinatesDS(this).createAreaCoordinates(coordinates2);
		coordinates2.setCoordinateId(coordinatesId2);
		
		AreaCoordinates coordinates3 =new AreaCoordinates();
		coordinates3.setCoordinateLatitude(6.924267);
		coordinates3.setCoordinateLongitude(79.854355);
		coordinates3.setCoordinateAreaId(areaId);
		int coordinatesId3=new AreaCoordinatesDS(this).createAreaCoordinates(coordinates3);
		coordinates3.setCoordinateId(coordinatesId3);
		
		//two polygon 
		AreaCoordinates coordinates4 =new AreaCoordinates();
		coordinates4.setCoordinateLatitude(6.921731);//6.921731, 80.002282
		coordinates4.setCoordinateLongitude(80.002282);
		coordinates4.setCoordinateAreaId(areaId1);
		int coordinatesId4=new AreaCoordinatesDS(this).createAreaCoordinates(coordinates4);
		coordinates4.setCoordinateId(coordinatesId4);
		
		AreaCoordinates coordinates5 =new AreaCoordinates();//6.844700, 80.151284
		coordinates5.setCoordinateLatitude(6.844700);
		coordinates5.setCoordinateLongitude(80.151284);
		coordinates5.setCoordinateAreaId(areaId1);
		int coordinatesId5=new AreaCoordinatesDS(this).createAreaCoordinates(coordinates5);
		coordinates5.setCoordinateId(coordinatesId5);
		
		
		AreaCoordinates coordinates6 =new AreaCoordinates();//6.765951, 79.927094
		coordinates6.setCoordinateLatitude(6.765951);
		coordinates6.setCoordinateLongitude(79.927094);
		coordinates6.setCoordinateAreaId(areaId1);
		int coordinatesId6=new AreaCoordinatesDS(this).createAreaCoordinates(coordinates6);
		coordinates6.setCoordinateId(coordinatesId6);
		
		AreaCoordinates coordinates7 =new AreaCoordinates();//6.942180, 79.904778
		coordinates7.setCoordinateLatitude(6.942180);
		coordinates7.setCoordinateLongitude(79.904778);
		coordinates7.setCoordinateAreaId(areaId1);
		int coordinatesId7=new AreaCoordinatesDS(this).createAreaCoordinates(coordinates7);
		coordinates7.setCoordinateId(coordinatesId7);
		
		/*
		 * testing coordinates : 6.851517, 79.991982
		 */
	}
	
	int delay = 1000; // delay for 1 sec. 
	int period = 30000; // repeat every 30 sec. 
	Timer timer = new Timer(); 
	
	@Override
	public void onGPSUpdate(Location location) {
		
		gpsTracker = new GPSTracker(this);
		speed = location.getSpeed();
		currentSpeed = round(speed, 3, BigDecimal.ROUND_HALF_UP);
		kmphSpeed = round((currentSpeed * 3.6), 3, BigDecimal.ROUND_HALF_UP);
		//kmphSpeed=30;
		
		txtview.setText(kmphSpeed + " km/h");
		
		float f = (float) kmphSpeed;
		
		speedometer.onSpeedChanged(f);
	
		final boolean status= setPolygon(gpsTracker.getLatitude(), gpsTracker.getLongitude());//checking isInside of that area 
		
		if(status){
			
			timer.scheduleAtFixedRate(new TimerTask() 
		    { 
		        public void run() 
		        { 
		        	Log.v("Timer", "every 30 sec");
		        	
		        	if(logic.givenCoordinateIsInside(kmphSpeed,status,gpsTracker.getLatitude(), gpsTracker.getLongitude(),areaId)){
						
						
						ttsMethod("Please reduce your vehicle speed.");
						Toast.makeText(MainActivity.this,"Status "+status, Toast.LENGTH_SHORT).show();
						
						
					}else{
						//timer.cancel();
					}
		        } 
		    }, delay, period); 
			
		}else{
			
			//timer.cancel();
			
		}
		
	 }
	
    public void ttsMethod(final String title){
    		
		tts =new TextToSpeech(this, new TextToSpeech.OnInitListener() {
			
			@Override
			public void onInit(int status) {
				// TODO Auto-generated method stub
				if(status !=TextToSpeech.ERROR);{
					tts.setLanguage(Locale.US);
					tts.speak(title, TextToSpeech.QUEUE_FLUSH, null);
				}
			}
		});
    }

	
	@Override
	protected void onPause() {
		// TODO Auto-generated method stub
		Log.d("Error Checking1", "TTS onPause");
		
		if(tts != null) {
			
			tts.stop();
	        tts.shutdown();
	        
	        Log.d("Error Checking", "TTS Destroyed");
	    }
		super.onPause();
		
	}
	
    @Override
	protected void onResume() {
    	//ttsMethod();//when display is off then onResume method will restart that TTS method
		super.onResume();
	}
    
	@Override
	protected void onDestroy() {
		gpsManager.stopListening();
		gpsManager.setGPSCallback(null);
		gpsManager = null;
		super.onDestroy();
	}

	public static double round(double unrounded, int precision, int roundingMode) {
		BigDecimal bd = new BigDecimal(unrounded);
		BigDecimal rounded = bd.setScale(precision, roundingMode);
		return rounded.doubleValue();
	}
}